package controllers

import command.CommandExec
import command.CommandPojo.CommandData
import dao._
import implicits.Implicits._
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}
import tool.{FormTool, Tool}
import utils.Utils

import java.io.File
import javax.inject.Inject
import scala.collection.immutable.SeqMap
import scala.concurrent.ExecutionContext.Implicits.global

/** Created by yz on 11/5/2020
  */
class ToolController @Inject() (cc: ControllerComponents)(
    implicit val prokaryoteDao: ProkaryoteDao,
    implicit val bioSampleDao: BioSampleDao,
    implicit val assemblyDao: AssemblyDao,
    implicit val modeDao: ModeDao
) extends AbstractController(cc) {

  def toGeoPredict = Action { implicit request =>
    Ok(views.html.tool.geoPredict())
  }

  def geoPredict = Action(parse.multipartFormData) { implicit request =>
    val tmpDir = Tool.createTempDirectory("tmpDir")
    val file = Tool.fileMoveDir("file", tmpDir)
    val commandExec = CommandExec()
      .exec { b =>
        val command =
          s"""
           |python3 ${Tool.pyPath.unixPath}/newKmer.py --in ${file.unixPath} --kmer 8 --out_dir ./split_features.csv
           |""".stripMargin
        CommandData(tmpDir, command)
      }
      .map { b =>
        val splitFile = new File(tmpDir, "split_features.csv")
        val sampleName = file.getName.fileNamePrefix
        val lines = splitFile.lines
        val header = lines.head
        val contents = lines.drop(1).reduceLeft { (line1, line2) =>
          val columns1 = line1.mySplit(",")
          val columns2 = line2.mySplit(",")
          columns1
            .zip(columns2)
            .map { case (x, y) =>
              if (x.isInt) {
                s"${x.toInt + y.toInt}"
              } else x
            }
            .mkString(",")
        }
        val finalContents = contents.mySplit(",").init :+ sampleName
        val newLines = List(header, finalContents.mkString(","))
        newLines.toFile(new File(tmpDir, "features.csv"))
      }
      .exec { b =>
        val command =
          s"""
           |${"python3".mambaPath(
              "nb"
            )} ${Tool.pyPath.unixPath}/newpredict.py --in features.csv --in_model ${Tool.dataDir.unixPath}/NB_model.pkl --out ./
           |""".stripMargin
        CommandData(tmpDir, command)
      }
    if (commandExec.isSuccess) {
      val file = new File(tmpDir, "results.txt")
      val lines = file.txtLines
      val maybeCountry = lines.head.tail.zip(lines.last.tail.map(_.toDouble)).maxBy(_._2)
      Ok(Json.obj("valid" -> true, "country" -> maybeCountry._1))
    } else {
      Ok(Json.obj("valid" -> false, "message" -> commandExec.errorInfo))
    }
  }

  def downloadExampleFile = Action { implicit request =>
    val data = FormTool.fileNameForm.bindFromRequest().get
    val file = new File(Tool.exampleDir, data.fileName)
    Ok.sendFile(file)
      .withHeaders(
        CONTENT_DISPOSITION -> Tool.getContentDisposition(s"${file.getName}"),
        CONTENT_TYPE -> "application/x-download"
      )
  }

}
